package com.slz3.business.module.systemManagement.sysMenu.service;

import com.slz3.business.frame.enums.ValidFlag;
import com.slz3.business.frame.module.Repositorys;
import com.slz3.business.frame.module.Services;
import com.slz3.business.frame.steward.PageableSteward;
import com.slz3.business.module.systemManagement.sysMenu.domain.SysMenu;
import com.slz3.business.module.systemManagement.sysMenu.domain.SysMenuFactory;
import com.slz3.business.module.systemManagement.sysMenu.steward.SysMenuSpecification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysMenuServiceImpl implements SysMenuService {

    @Override
    public SysMenu save(SysMenu sysMenu) {
        return Repositorys.sysMenu.save(SysMenuFactory.initBaseFields(sysMenu));
    }

    @Override
    public Page<SysMenu> page(MultiValueMap<String, String> params) {
        Page<SysMenu> sysMenuPage = Repositorys.sysMenu.findAll(
                SysMenuSpecification.findJoin(params), PageableSteward.extract(params)
        );
        Map<UUID, SysMenu> collect = Repositorys.sysMenu.findAllById(
                sysMenuPage.stream().map(SysMenu::getParentId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList())
        ).stream().collect(Collectors.toMap(SysMenu::getUuid, Function.identity()));
        sysMenuPage.stream().forEach(item -> item.setParentMenu(collect.get(item.getParentId())));
        return sysMenuPage;
    }

    @Override
    public SysMenu modify(SysMenu sysMenuNew) {
        return Repositorys.sysMenu.saveAndFlush(SysMenuFactory.initBaseFields(sysMenuNew));
    }

    @Override
    public Optional<SysMenu> single(UUID uuid) {
        return Repositorys.sysMenu.findById(uuid);
    }

    @Override
    public List<SysMenu> findAllByUuids(Iterable<UUID> uuids) {
        return Repositorys.sysMenu.findAllById(uuids);
    }

    @Override
    public List<SysMenu> delete(List<SysMenu> sysMenuList) {
        sysMenuList.stream().forEach(item -> {
            item.setValidFlag(ValidFlag.DEL);
            SysMenuFactory.initBaseFields(item);
        });
        return Services.sysMenuTransactional.batchModify(sysMenuList);
    }

    @Override
    public List<SysMenu> listAllMenu() {
        List<SysMenu> sysMenus = Repositorys.sysMenu.queryByParentIdIsNull();
        if (CollectionUtils.isEmpty(sysMenus)){
            return null;
        }
        for (SysMenu item : sysMenus){
            item.setChildren(Repositorys.sysMenu.queryByParentId(item.getUuid()));
        }
        return sysMenus;
    }

    @Override
    public List<SysMenu> listMenuByLogin(UUID loginUserUuid) {
        List<SysMenu> sysMenus = Repositorys.sysMenu.queryRootMenu(loginUserUuid);
        if (CollectionUtils.isEmpty(sysMenus)){
            return null;
        }
        for (SysMenu item : sysMenus){
            item.setChildren(Repositorys.sysMenu.queryChildrenMenu(loginUserUuid, item.getUuid()));
        }
        return sysMenus;
    }

    @Override
    public List<SysMenu> findAll(SysMenu params) {
        params.setValidFlag(ValidFlag.VALID);
        Example<SysMenu> of = Example.of(params);
        return Repositorys.sysMenu.findAll(of);
    }
}
